﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WorldViewSolutions.ArcGISServer.SOE
{
    /// <summary>
    /// 
    /// </summary>
    /// <remarks></remarks>
    public class Registration
    {
        /// <summary>
        /// 
        /// </summary>
        private const string _host = "localhost";
        /// <summary>
        /// 
        /// </summary>
        private const string _namespace = "WorldViewSolutions.ArcGISServer.SOE.";

        /// <summary>
        /// Initializes a new instance of the <see cref="T:System.Object"/> class.
        /// </summary>
        /// <remarks></remarks>
        public Registration()
        {

        }

        /// <summary>
        /// Registers the specified extension name.
        /// </summary>
        /// <param name="extensionName">Name of the extension.</param>
        /// <param name="description">The description.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        public string Register(string extensionName, string description)
        {
            string message = null;

            // Must run as an user in the agsadmin group on the SOM
            using (ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection agsServerConnection = new ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection(_host, null, true))
            {
                ESRI.ArcGIS.Server.IServerObjectAdmin2 serverObjectAdmin = agsServerConnection.ServerObjectAdmin as ESRI.ArcGIS.Server.IServerObjectAdmin2;

                // Check whether the SOE is registered
                if (!ExtensionRegistered(serverObjectAdmin, extensionName))
                {
                    // Use IServerObjectExtensionType3 to get access to info properties
                    ESRI.ArcGIS.Server.IServerObjectExtensionType3 serverObjectExtensionType = serverObjectAdmin.CreateExtensionType() as ESRI.ArcGIS.Server.IServerObjectExtensionType3;

                    // Must match the namespace and class name of the class implementing IServerObjectExtension
                    serverObjectExtensionType.CLSID = _namespace + extensionName;
                    serverObjectExtensionType.Description = description;
                    serverObjectExtensionType.Name = extensionName;

                    // Name that will be shown in the capabilities list on property pages
                    serverObjectExtensionType.DisplayName = extensionName;

                    // Use info properties to define capabilities and msd support
                    serverObjectExtensionType.Info.SetProperty("SupportsMSD", "true");

                    // Required to enable exposure of SOE with ArcGIS Server REST endpoint
                    serverObjectExtensionType.Info.SetProperty("SupportsREST", "true");

                    // Register the SOE with the server
                    serverObjectAdmin.AddExtensionType("MapServer", serverObjectExtensionType);

                    message = extensionName + " successfully registered with ArcGIS Server.";
                }
                else
                {
                    message = extensionName + " is already registered with ArcGIS Server.";
                }
            }

            return message;
        }

        /// <summary>
        /// Unregisters the specified extension name.
        /// </summary>
        /// <param name="extensionName">Name of the extension.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        public string Unregister(string extensionName)
        {
            string message = null;

            // Must run as an user in the agsadmin group on the SOM
            using (ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection connection = new ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection(_host, null, true))
            {
                ESRI.ArcGIS.Server.IServerObjectAdmin2 serverObjectAdmin = connection.ServerObjectAdmin as ESRI.ArcGIS.Server.IServerObjectAdmin2;

                // This name must match those defined for property pages 


                // Check whether the SOE is registered
                if (ExtensionRegistered(serverObjectAdmin, extensionName))
                {
                    // Delete the SOE
                    serverObjectAdmin.DeleteExtensionType("MapServer", extensionName);
                    message = extensionName + " successfully unregistered.";
                }
                else
                {
                    message = extensionName + " is not registered with ArcGIS Server.";
                }
            }

            return message;
        }

        // Checks whether an extension with the passed-in name is already registered with the passed-in server
        /// <summary>
        /// Extensions the registered.
        /// </summary>
        /// <param name="serverObjectAdmin">The server object admin.</param>
        /// <param name="extensionName">Name of the extension.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        static private bool ExtensionRegistered(ESRI.ArcGIS.Server.IServerObjectAdmin2 serverObjectAdmin, string extensionName)
        {
            // Get the extensions that extend MapServer server objects
            ESRI.ArcGIS.Server.IEnumServerObjectExtensionType extensionTypes = serverObjectAdmin.GetExtensionTypes("MapServer");
            extensionTypes.Reset();

            // If an extension with a name matching that passed-in is found, return true
            ESRI.ArcGIS.Server.IServerObjectExtensionType extensionType = extensionTypes.Next();
            while (extensionType != null)
            {
                if (extensionType.Name == extensionName)
                    return true;

                extensionType = extensionTypes.Next();
            }

            // No matching extension was found, so return false
            return false;
        }
    }
}
